<?php

namespace app\common\webdav\auth\backend;

use app\admin\model\HomeUser;
use Sabre\DAV\Auth\Backend\AbstractDigest;
use think\facade\Config;
use think\facade\Log;
use Sabre\DAV;
use Sabre\HTTP;
use Sabre\HTTP\RequestInterface;
use Sabre\HTTP\ResponseInterface;

class Model extends AbstractDigest
{


    protected $digest = null;

    public function getDigestHash($realm, $username)
    {

        $hash = '';

        $model_user = HomeUser::where('username', $username)->autoCache('read_by_username', $username)->find();

        if (!empty($model_user)) {
            $hash = $model_user->webdav_password;
        }

        return $hash;
    }

    /**
     * When this method is called, the backend must check if authentication was
     * successful.
     *
     * The returned value must be one of the following
     *
     * [true, "principals/username"]
     * [false, "reason for failure"]
     *
     * If authentication was successful, it's expected that the authentication
     * backend returns a so-called principal url.
     *
     * Examples of a principal url:
     *
     * principals/admin
     * principals/user1
     * principals/users/joe
     * principals/uid/123457
     *
     * If you don't use WebDAV ACL (RFC3744) we recommend that you simply
     * return a string such as:
     *
     * principals/users/[username]
     *
     * @return array
     */
    public function check(RequestInterface $request, ResponseInterface $response)
    {
        if(is_null($this->digest)){
            $this->digest = new HTTP\Auth\Digest(
                $this->realm,
                $request,
                $response
            );
            $this->digest->init();
        }

        $username = $this->digest->getUsername();

        // No username was given
        if (!$username) {
            return [false, "No 'Authorization: Digest' header found. Either the client didn't send one, or the server is misconfigured"];
        }

        $hash = $this->getDigestHash($this->realm, $username);
        // If this was false, the user account didn't exist
        if (false === $hash || is_null($hash)) {
            return [false, 'Username or password was incorrect'];
        }
        if (!is_string($hash)) {
            throw new DAV\Exception('The returned value from getDigestHash must be a string or null');
        }

        // If this was false, the password or part of the hash was incorrect.
        if (!$this->digest->validateA1($hash)) {
            return [false, 'Username or password was incorrect'];
        }

        return [true, $this->principalPrefix . $username];
    }

    public function getUsername()
    {
        return $this->digest->getUsername();
    }

    public static function buildDigestHash($username, $password)
    {
        $realm = Config::get('webdav.realm', 'uldisk');

        return md5($username . ':' . $realm . ':' . $password);
    }
}
